# Manage feed subscriptions.

import OPML
import download
import index
import db
import diskmgr
import traceback
from feed import Feed
from log import log

class DuplicateSubscription(Exception):
  pass

def ImportOPML(filename):
  opml = OPML.parse(open(filename, 'r'))
  for outline in opml.outlines:
    try:
      Subscribe(outline['xmlUrl'])
    except DuplicateSubscription:
      log("Duplicate subscription in opml - continuing")

def Load():
  for row in db.Select(Feed.Columns(), "feeds"):
    feed = Feed(row)
    index.Add(feed)
    download.AddFeed(feed)
  try:
    diskmgr.DeleteDanglingFeeds(index.FeedIDs())
  except:
    log("ERROR: Could not delete dangling feeds")
    log(traceback.format_exc())

def Subscribe(url):
  """Will raise DuplicateSubscription if url already belongs to one of the
  subscribed feeds."""
  log("SUBSCRIBE REQUEST:",url)
  feed = index.AddIfUnique(lambda: Feed.Create(url), url)
  if feed is None:
    log("Duplicate subscription request on url:", url)
    raise DuplicateSubscription()
  download.AddFeed(feed)

def Unsubscribe(feed):
  log("UNSUBSCRIBE REQUEST:",feed)

  # If the feed is currently being downloaded then setting this flag true will
  # prevent it from being added back into the pool of uptodate/waiting feeds.
  # The next time it is dequeued it will be dropped.
  download.RemoveFeed(feed)

  # Remove the feed from the index.
  index.Remove(feed.feed_id())
